﻿
using System;
using System.Collections.Generic;
using System.Data;

namespace Anno.DynamicApi
{
    /// <summary>
    /// 调用远程的Web Api接口
    /// </summary>
    public class RemoteApiExecutor : BaseExecutor
    {
        public RemoteApiExecutor(ApiInfo apiInfo) : base(apiInfo, ExecutorType.RemoteApi)
        {
        }
        /// <summary>
        /// URL地址
        /// </summary>
        public string BaseUri { get; set; }

        /// <summary>
        /// 用于服务操作的统一资源标识符 (URI) 模板。返回结果: 用于服务操作的 URI 模板。
        /// </summary>
        public string Route { get; set; }
        //---------------------------------------------------------------------------------------------------------------------------------
        string _FullClassName = "";
        /// <summary>
        /// 类名
        /// </summary>
        private string FullClassName
        {
            get
            {
                if (_FullClassName.IsNullOrEmpty())
                    _FullClassName = string.IsNullOrEmpty(ApiInfo?.KeyWord) ? $"C{Guid.NewGuid().ToString("N")}E" : ApiInfo?.KeyWord + "_FullClassNamer";
                return _FullClassName;
            }
        }

        string _ActionMethod = "";
        /// <summary>
        /// 执行方法
        /// </summary>
        private string Method
        {
            get
            {
                if (_ActionMethod.IsNullOrEmpty())
                    _ActionMethod = string.IsNullOrEmpty(ApiInfo?.KeyWord) ? $"A{Guid.NewGuid().ToString("N")}E" : ApiInfo?.KeyWord + Guid.NewGuid().ToString("N") + "_ActionMethodr";
                return _ActionMethod;
            }
        }
        public void RemoveActionMethod()
        {
            RuntimeCodeCompiler.RemoveFromCache(Method);
        }
        //---------------------------------------------------------------------------------------------------------------------------------
        public RemoteApiExecutor(System.Xml.XmlNode xmlNode, ApiInfo apiInfo) : base(xmlNode, apiInfo, ExecutorType.RemoteApi)
        {
            if (xmlNode == null || apiInfo == null || xmlNode.NodeType == System.Xml.XmlNodeType.Comment)
            {
                return;
            }
            Init(xmlNode, apiInfo);
        }
		public RemoteApiExecutor(Newtonsoft.Json.Linq.JToken xmlNode, ApiInfo apiInfo) : base(xmlNode, apiInfo, ExecutorType.RemoteApi)
        {
            if (xmlNode == null || apiInfo == null)
            {
                return;
            }
            Init(xmlNode, apiInfo);
        }
        public override void Init(System.Xml.XmlNode ExecutorNode, ApiInfo apiInfo)
        {
            base.Init(ExecutorNode, apiInfo);
            try
            {
                if (ExecutorNode == null || apiInfo == null || ExecutorNode.NodeType == System.Xml.XmlNodeType.Comment)
                {
                    return;
                }
                Name = ExecutorNode.GetXmlNodeAttributeValue("Name", Name);
                BaseUri = ExecutorNode.GetXmlNodeAttributeValue("BaseUri");
                Route = ExecutorNode.GetXmlNodeAttributeValue("Route", apiInfo.Route);
            }
            catch { }
        }
        public override void Init(Newtonsoft.Json.Linq.JToken ExecutorNode, ApiInfo apiInfo)
        {
            base.Init(ExecutorNode, apiInfo);
            try
            {
                if (ExecutorNode == null || apiInfo == null)
                {
                    return;
                }
                Name = ExecutorNode.GetXmlNodeAttributeValue("Name", Name);
                BaseUri = ExecutorNode.GetXmlNodeAttributeValue("BaseUri");
                Route = ExecutorNode.GetXmlNodeAttributeValue("Route", apiInfo.Route);
            }
            catch { }
        }
        ///// <summary>
        ///// 返回JSON对象
        ///// </summary>
        //public override object JObject
        //{
        //    get
        //    {
        //        var bJObject = base.JObject as IDictionary<string, object>;

        //        bJObject[nameof(BaseUri)] = BaseUri;
        //        bJObject[nameof(Route)] = Route;

        //        return bJObject;
        //    }
        //}
        public override IDictionary<string, object> DicAttrs
        {
            get
            {
                var bJObject = base.DicAttrs;

                bJObject[nameof(BaseUri)] = BaseUri;
                bJObject[nameof(Route)] = Route;

                return bJObject;
            }
        }
        //---------------------------------------------------------------------------------------------------------------------------------
        protected override object Executor(object input)
        {
            try
            {
                var rminfo = ControllerList.GetBaseUri(BaseUri, null);
                if (rminfo == null) return ApiResult.Faild($"RemoteUri信息配置错误,{BaseUri}未配置");
                if (rminfo.BaseUri.IsNullOrEmpty()) return ApiResult.Faild($"RemoteUri信息配置错误,{BaseUri}配置不能为空");
                var url = rminfo.BaseUri;
                if (!url.ToLower().Contains("/" + Route.Trim('/').ToLower()))
                {
                    url = url.TrimEnd('/') + "/" + Route.Trim('/');
                }

                IDictionary<string, string> urlparameters = null;// PubFun.GetQueryParameters(request);
                var txtPostData = input.NullToStr();
                //--------------------------------------------------------------------------------------------------------------------
                var response = HttpHelper.Instance.RequestAsync(ApiInfo.HttpMethod, url, txtPostData, headers, urlparameters).Result;
                response.EnsureSuccessStatusCode();
                if (response.StatusCode == System.Net.HttpStatusCode.OK)
                {
                    var retstr = response.Content.ReadAsStringAsync().Result;
                    var jsret = retstr.JsonToObject<object>();

                    return getJsonResult(jsret);
                }
                return ApiResult.Faild($"调用失败:{url},ReasonPhrase:" + response.ReasonPhrase);
            }
            catch (Exception ex)
            {
                return ApiResult.Exception(ex);
                //throw ex;

                //var error =ex.GetExceptionMessage();
                //Console.WriteLine(error);
                //Log.Log.Error(error);
                //return null;
            }
        }
    }
}
